using Gtk;
using NHibernate;
using System;
using System.Collections;
using System.Data;

namespace Serpis
{
	internal class TreeViewHelper
	{
		private TreeView treeView;
		private ListStore listStore;
		private string commandText;
		
		public TreeViewHelper (TreeView treeView, string commandText)
		{
			this.treeView = treeView;
			Refresh(commandText);
			
			treeView.Selection.Changed += delegate {
				raiseChanged();
			};
		}
		
		private void upToDateTreeView(string commandText, IQuery query)
		{
			if (this.commandText == commandText)
				return;
			this.commandText = commandText;
								
			foreach (TreeViewColumn treeViewColumn in treeView.Columns)
				treeView.RemoveColumn(treeViewColumn);
			
			string[] aliases=query.ReturnAliases;
			Type[] types = new Type[aliases.Length];
			
			for (int i = 0; i < aliases.Length; i++) {
				treeView.AppendColumn(aliases[i], new CellRendererText(), "text", i);
				types[i] = typeof(string);
			}
			listStore = new ListStore(types);
		}
		
		private void fillListStore(IQuery query)
		{
			listStore.Clear();
			
			IList list=query.List();
			string[] aliases=query.ReturnAliases;
			
			foreach (object[] row in list) {				
				object[] values = new object[aliases.Length];
				
				for (int i = 0; i < values.Length; i++)
					values[i]= row[i].ToString();
				
				listStore.AppendValues(values);
			}
			
			treeView.Model = listStore;
		}
		
		public void Refresh(string commandText)
		{	
			ISession session=AppDbConnection.Instance.SessionFactory.OpenSession();
			IQuery query=session.CreateQuery(commandText);
			upToDateTreeView(commandText,query);	
			fillListStore(query);
			session.Close();
		}
		
		public void Refresh()
		{
			Refresh(commandText);
		}
		
		public bool HasSelected {
			get { return treeView.Selection.CountSelectedRows() > 0;} 
		}
		
		/// <summary>
		/// Devuelve el valor de la columna indicada de la fila seleccionada.
		/// Precondición: El método supone, y no lo comprueba, que hay una fila seleccionada.
		/// </summary>
		public object GetValue(int columnIndex)
		{
			TreeIter treeIter;
			treeView.Selection.GetSelected(out treeIter);
						
			return listStore.GetValue(treeIter, columnIndex);
		}
		
		private void raiseChanged()
		{
			if (Changed != null)
				Changed(this, EventArgs.Empty);
		}

		public event EventHandler Changed;
	}
}
